home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / More Source / C⁄C++ / AIFF DSP v22 / plugin_src / chebyshev.c < prev    next >
Text File  |  1995-01-30  |  2KB  |  80 lines

  1. /* implements a nonlinear transfer function using Chebyshev polynomials of user-specified order. */
  2.  
  3. #include "plugin_specific.h"
  4. #include "aiff.h"
  5. #include "num_input_macros.h"
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <limits.h>
  9.  
  10. #define MAXORDER   16                /* MAX. ORDER of chebyshev polynomial */
  11. #define CILOG2     11                /* see below */
  12. #define CHECK_INC  ( 1U << CILOG2 )  /* period of progress report, */
  13.                                      /* in table entries */
  14. static short *xferfunc;
  15.  
  16. void init_process_chebyshev( void ) {
  17.    short i, t, *txferfunc, order;
  18.    double twox, *tp;
  19.    double p[MAXORDER] = {1};
  20.  
  21.    if ( (nh.wdsi < 9) || (nh.wdsi > 16) )
  22.       err( "Cannot process a file with this word size" );
  23.  
  24.    if ( USHRT_MAX != 65535 )
  25.       err( "this plugin is based on the assumption of 2 byte shorts" );
  26.  
  27.    if (!(xferfunc = malloc( 0x20000 )))
  28.       err( "Couldn't allocate transfer function table memory" );
  29.    
  30.    GET_NUM_RANGE( "order", "%hd", "%hd", order, 1, MAXORDER );
  31.    
  32.    fputs( "Generating transfer function table...\n" , stderr);
  33.    for (i=0; i < 0x10000 / CHECK_INC; i++) fputc( '*', stderr );
  34.    fputc( '\n', stderr );
  35.  
  36.    txferfunc = xferfunc;
  37.    i = -0x8000;
  38.    do {
  39.       if ((i % CHECK_INC) == 0)         /* progress report time */
  40.          fputc( '*', stderr );
  41.       
  42.       tp = &p[1];
  43.       *tp = (double) i / 0x8000;
  44.       twox = *tp * 2;
  45.  
  46.       for ( t=2; t<=order; t++ ) {
  47.          tp++;
  48.          *tp = *(tp-1) * twox  -  *(tp-2);
  49.       }
  50.       
  51.       *txferfunc++ = *tp * 0x7FFE; /* 1 */
  52.    } while ( i++ < 0x7FFF);
  53.    
  54.    fputs( "\n\n", stderr );
  55. }
  56. /* 1. assumes |*tp|/1 <= 0x7FFF/0x7FFE */
  57.  
  58. void term_process_chebyshev ( void ) {
  59.    free( xferfunc );
  60. }
  61.  
  62. void process_samdat_chebyshev ( long buflen ) {
  63.    register short *td, *endd, *txferfunc;
  64.    
  65.    td        = d;
  66.    txferfunc = xferfunc;
  67.    endd      = &td[nh.chan * buflen];
  68.    
  69.    do {
  70.       *td++ = txferfunc[ 0x8000 + *td ];
  71.    } while ( td < endd );
  72. }
  73. plugin_info plugin_chebyshev = {
  74.    init_process_chebyshev,
  75.    term_process_chebyshev,
  76.    process_samdat_chebyshev,
  77.    1, /* take_input */
  78.    1  /* make_output */
  79. };
  80.